package com.shuiyun.chat.client;

import com.google.gson.Gson;
import com.shuiyun.chat.config.NettyConfig;
import com.shuiyun.chat.entity.message.LoginResponseMessage;
import com.shuiyun.chat.entity.message.ReceiveGroupMessage;
import com.shuiyun.chat.entity.message.SimpleChatMessage;
import com.shuiyun.chat.handler.LengthFieldDecoder;
import com.shuiyun.chat.handler.MessageCodecHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CountDownLatch;

/**
 * @program: chatServer
 * @description: 聊天客户端
 * @author: shuiyun
 * @create: 2021-05-12 22:43
 **/
@Slf4j
public class ChatClient {

    private Bootstrap bootstrap = null;
    private final NioEventLoopGroup worker = new NioEventLoopGroup();
    private final MessageCodecHandler messageCodecHandler = new MessageCodecHandler();
    @Getter
    private LoginResponseMessage loginMessage;

    public ChatClient(CountDownLatch wait){
        bootstrap = new Bootstrap().channel(NioSocketChannel.class).group(worker).handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel socketChannel) throws Exception {
                ChannelPipeline pipeline = socketChannel.pipeline();
                pipeline.addLast(new LoggingHandler(LogLevel.DEBUG));
                // 定长解码器 解决半包和黏包
                pipeline.addLast(new LengthFieldDecoder());
                pipeline.addLast(messageCodecHandler);
                // 登录
                pipeline.addLast(new SimpleChannelInboundHandler<LoginResponseMessage>() {
                    @Override
                    protected void channelRead0(ChannelHandlerContext channelHandlerContext, LoginResponseMessage loginResponseMessage) throws Exception {
                        loginMessage = loginResponseMessage;
                        // 唤醒主线程
                        wait.countDown();
                    }
                });
                // 私聊
                pipeline.addLast(new SimpleChannelInboundHandler<SimpleChatMessage>() {
                    @Override
                    protected void channelRead0(ChannelHandlerContext channelHandlerContext, SimpleChatMessage simpleChatMessage) throws Exception {
                        log.info("{}对{}说 ：{}",simpleChatMessage.getSrc(),simpleChatMessage.getTo(),simpleChatMessage.getMessage());
                    }
                });
                // 群聊
                pipeline.addLast(new SimpleChannelInboundHandler<ReceiveGroupMessage>() {
                    @Override
                    protected void channelRead0(ChannelHandlerContext channelHandlerContext, ReceiveGroupMessage receiveGroupMessage) throws Exception {
                        log.info("{}接收到来自群：{} {}的群消息：{}",receiveGroupMessage.getReceiverName(),receiveGroupMessage.getGroupName(),receiveGroupMessage.getUserName(),receiveGroupMessage.getMessage());
                    }
                });
            }
        });
    }

    public Channel connect(String tcpIp,Integer tcpPort){
        try {
            Channel channel = bootstrap.connect(tcpIp, tcpPort).sync().channel();
            channel.closeFuture().addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture channelFuture) throws Exception {
                    worker.shutdownGracefully();
                }
            });
            return channel;
        }catch (Exception e){
            log.error("连接服务器失败:",e);
            return null;
        }
    }
}
